package com.mushiengine.core {
import asmock.framework.Expect;

import asmock.framework.constraints.Is;

import com.mushiengine.collection.HashMap;
import com.mushiengine.collection.IMap;
import com.mushiengine.test.MockTestCase;
import com.mushiengine.test.objects.ExampleBean;
import com.mushiengine.test.objects.InjectedBean;

public class BeanLoaderTest extends MockTestCase{

    private var _mockBeanDefLoader:IBeanDefinitionLoader;
    private var _mockHashMap:IMap;
    private var _mockInjector:IInjector;
    private var _beanLoader:BeanLoader;

    public function BeanLoaderTest() {
        super([IMap,IBeanDefinitionLoader, IInjector]);
    }


    public override function setUp():void {
        super.setUp();
        _mockBeanDefLoader = IBeanDefinitionLoader(mockRepository.createStrict(IBeanDefinitionLoader));
        _mockHashMap = IMap(mockRepository.createStrict(IMap));
        _mockInjector = IInjector(mockRepository.createStrict(IInjector));

        _beanLoader = new BeanLoader(_mockHashMap, _mockInjector);


    }

    public function testThatgetDescriptionsIsCalled():void {
        var testDefinitionMap:IMap = genDescMap();
        Expect.call(_mockBeanDefLoader.getDescriptions()).returnValue(genDescMap());
        Expect.call(_mockInjector.injectViaClass(ExampleBean)).returnValue(new ExampleBean()).constraints([
            Is.notNull()
        ]).repeat.twice();
        Expect.call(_mockHashMap.put("", "")).constraints([
            Is.notNull(),
            Is.notNull()
        ]).repeat.twice();
        Expect.call(_mockHashMap.getValue("")).constraints([
            Is.notNull()
        ]).repeat.twice().returnValue(null);
        mockRepository.replayAll();
        _beanLoader.loadBeanDefinition(_mockBeanDefLoader);
        mockRepository.verifyAll();
    }

    //    public function xtestThatCorrectInstanceIsCreated():void {
    //        Expect.call(_mockBeanDefLoader.getDescriptions()).returnValue(genDescMap());
    //        Expect.call(_mockInjector.injectViaClass(InjectedBean)).constraints([
    //            Is.notNull()
    //        ]).returnValue(new InjectedBean());
    //        Expect.call(_mockInjector.injectViaClass(ExampleBean)).constraints([
    //            Is.notNull()
    //        ]).returnValue(new ExampleBean());
    //
    //        mockRepository.replayAll();
    //        _beanLoader.loadBeanDefinition(_mockBeanDefLoader);
    //        assertTrue(Diggbe.getBean("expBean") is ExampleBean);
    //        assertTrue(Diggbe.getBean("injectedBean") is InjectedBean);
    //
    //        mockRepository.verifyAll();
    //    }
    //
    private function genDescMap():IMap {
        var map:IMap = new HashMap();

        map.put("expBean", "com.mushiengine.test.objects::ExampleBean");
        map.put("injectedBean", "com.mushiengine.test.objects::InjectedBean");

        return map;
    }

    public function testInjectorIsCalledWhenInstanceIsCreated():void {
        var injBean:InjectedBean = new InjectedBean();

        Expect.call(_mockInjector.injectViaClass(InjectedBean)).ignoreArguments().returnValue(injBean).repeat.twice();
        Expect.call(_mockHashMap.put("", "")).ignoreArguments().repeat.twice();
        Expect.call(_mockHashMap.getValue("")).constraints([
            Is.notNull()
        ]).repeat.twice().returnValue(null);
        mockRepository.replayAll();
        _beanLoader.grabBeanClassFromDefinition(genDescMap());
        mockRepository.verifyAll();
    }

    public function testInjectorIsCalledWhenAnInstanceIsPassedIn():void {
        var injBean:InjectedBean = new InjectedBean();
        Expect.call(_mockInjector.injectViaInstance(injBean)).returnValue(injBean).constraints(
                [
                    Is.notNull()
                ]
                ).returnValue(injBean);
        Expect.call(_mockHashMap.put("inject3", injBean));
        Expect.call(_mockHashMap.getValue("")).constraints([
            Is.notNull()
        ]).returnValue(null);
        mockRepository.replayAll();
        _beanLoader.addbean("inject3", injBean);
        mockRepository.verifyAll();
    }

    public function testAbleToGetBean():void {
        Expect.call(_mockHashMap.getValue("expBean3")).returnValue(new ExampleBean());
        mockRepository.replayAll();
        assertTrue(_beanLoader.getBean("expBean3") is ExampleBean);
        mockRepository.verifyAll();
    }

    public function testShouldCheckThatExpectationAreMetWhenBeanIsSetToRemove():void {

        Expect.call(_mockHashMap.remove("")).constraints([Is.notNull()]);
        mockRepository.replayAll();
        _beanLoader.removeBean("expBean4");
        mockRepository.verifyAll();
    }

//    public function testShouldNotCallInjectWhenBeanAlreadyExist():void {
//        var injBean:InjectedBean = new InjectedBean();
//        Expect.call(_mockHashMap.put("inject3", injBean));
//        Expect.call(_mockHashMap.getValue("inject3")).returnValue(injBean);
//        mockRepository.replayAll();
//        _beanLoader.addbean("inject3", injBean);
//        mockRepository.verifyAll();
//    }
}
}